package me.mingshan.leetcode;

/**
 * https://leetcode.cn/problems/rectangle-area/description/
 *
 * 给你 二维 平面上两个 由直线构成且边与坐标轴平行/垂直 的矩形，请你计算并返回两个矩形覆盖的总面积。
 *
 * 每个矩形由其 左下 顶点和 右上 顶点坐标表示：
 *
 * 第一个矩形由其左下顶点 (ax1, ay1) 和右上顶点 (ax2, ay2) 定义。
 * 第二个矩形由其左下顶点 (bx1, by1) 和右上顶点 (bx2, by2) 定义。
 *
 *
 * @author hanjuntao
 * @date 2025/6/30 0030
 */
public class L_223_rectangle_area {
    public static void main(String[] args) {
        int[] rec1 = {-3, 0, 3, 4};
        int[] rec2 = {0, -1, 9, 2};
        //System.out.println(computeArea(rec1[0], rec1[1], rec1[2], rec1[3], rec2[0], rec2[1], rec2[2], rec2[3]));

        int[] rec3 = {-2, -2, 2, 2};
        int[] rec4 = {-3, -3, 3, 1};
        // 24 + 16 = 40
        //System.out.println(computeArea(rec3[0], rec3[1], rec3[2], rec3[3],
        //        rec4[0], rec4[1], rec4[2], rec4[3]));

        int[] rec5 = {-5, -2, 5, 1};
        int[] rec6 = {-3, -3, 3, 3};
        System.out.println(computeArea(rec5[0], rec5[1], rec5[2], rec5[3],
                rec6[0], rec6[1], rec6[2], rec6[3]));


        System.out.println(computeArea(-2, -2, 2, 2, -1, 4, 1, 6));

    }

    public static int computeArea(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) {
        int area = Math.abs(ax2 - ax1) * Math.abs(ay2 - ay1)
                + Math.abs(bx2 - bx1) * Math.abs(by2 - by1);

        int i = computeArea3(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2);

        return area - i;
    }

    /**
     * 相交面积：
     * <p>
     * 判断A矩形，哪个角在B矩形内
     * <p>
     * 判断B矩形，哪个角在A矩形内
     *
     * @param ax1
     * @param ay1
     * @param ax2
     * @param ay2
     * @param bx1
     * @param by1
     * @param bx2
     * @param by2
     * @return
     */
    private static int computeArea2(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) {
        boolean a1IsInRectangle = isInRectangle(ax1, ay1, bx1, by1, bx2, by2);
        boolean a2IsInRectangle = isInRectangle(ax2, ay1, bx1, by1, bx2, by2);
        boolean a3IsInRectangle = isInRectangle(ax2, ay2, bx1, by1, bx2, by2);
        boolean a4IsInRectangle = isInRectangle(ax1, ay2, bx1, by1, bx2, by2);


        boolean b1IsInRectangle = isInRectangle(bx1, by1, ax1, ay1, ax2, ay2);
        boolean b2IsInRectangle = isInRectangle(bx2, by1, ax1, ay1, ax2, ay2);
        boolean b3IsInRectangle = isInRectangle(bx2, by2, ax1, ay1, ax2, ay2);
        boolean b4IsInRectangle = isInRectangle(bx1, by2, ax1, ay1, ax2, ay2);

        if (!a1IsInRectangle && !a2IsInRectangle && !a3IsInRectangle && !a4IsInRectangle
                && !b3IsInRectangle && !b4IsInRectangle && !b1IsInRectangle && !b2IsInRectangle) {

            // 所有角都不在，两种情况：
            // 1. 完全没有重叠
            // 2. 十字重叠
            if (ax1 < bx1 && ax2 > bx1
                    && ax1 < bx2 && ax2 > bx2
                    && ay2 < by2 && ay2 > by1
                    && ay1 < by2 && ay1 > by1) {
                return Math.abs(bx2 - bx1) * Math.abs(ay2 - ay1);
            } else if (bx1 < ax1 && bx2 > ax1
                    && bx1 < ax2 && bx2 > ax2
                    && by2 < ay2 && by2 > ay1
                    && by1 < ay2 && by1 > ay1){
                return Math.abs(ax2 - ax1) * Math.abs(by2 - by1);
            } else {
                return 0;
            }
        }

        if (a1IsInRectangle && a2IsInRectangle && a3IsInRectangle && a4IsInRectangle) {
            return Math.abs(ax2 - ax1) * Math.abs(ay2 - ay1);
        }

        if (b1IsInRectangle && b2IsInRectangle && b3IsInRectangle && b4IsInRectangle) {
            return Math.abs(bx2 - bx1) * Math.abs(by2 - by1);
        }

        int width;
        int height;

        if (a3IsInRectangle && b1IsInRectangle) {
            // a矩形右上角 b矩形右下角
            // A: X: ax2, Y: ay2
            // B: X: bx1, Y: by1
            width = Math.abs(ax2 - bx1);
            height = Math.abs(ay2 - by1);

            return Math.abs(width) * Math.abs(height);
        }

        if (a2IsInRectangle && b4IsInRectangle) {
            // A矩形右下角在B矩形左上角
            // A: X: ax2, Y: ay1
            // B: X: bx1, Y: by2
            width = Math.abs(ax2 - bx1);
            height = Math.abs(ay1 - by2);

            return Math.abs(width) * Math.abs(height);
        }

        if (a1IsInRectangle && b3IsInRectangle) {
            // A矩形左下角在B矩形右上角
            // A: X: ax1, Y: ay1
            // B: X: bx2, Y: by2
            width = Math.abs(ax1 - bx2);
            height = Math.abs(ay1 - by2);

            return Math.abs(width) * Math.abs(height);
        }

        if (a4IsInRectangle && b2IsInRectangle) {
            // A矩形左上角在B矩形右下角
            // A: X: ax1, Y: ay2
            // B: X: bx2, Y: by1
            width = Math.abs(ax1 - bx2);
            height = Math.abs(ay2 - by1);

            return Math.abs(width) * Math.abs(height);
        }

        // A两个角都在
        if (a1IsInRectangle && a2IsInRectangle) {
            width = Math.abs(ax2 - ax1);
            height = Math.abs(ay1 - by2);

            return Math.abs(width) * Math.abs(height);
        }

        if (a2IsInRectangle && a3IsInRectangle) {
            width = Math.abs(ax2 - bx1);
            height = Math.abs(ay1 - ay2);

            return Math.abs(width) * Math.abs(height);
        }

        if (a3IsInRectangle && a4IsInRectangle) {
            width = Math.abs(ax2 - ax1);
            height = Math.abs(ay2 - by1);

            return Math.abs(width) * Math.abs(height);
        }

        if (a4IsInRectangle && a1IsInRectangle) {
            width = Math.abs(ax1 - bx2);
            height = Math.abs(ay2 - ay1);

            return Math.abs(width) * Math.abs(height);
        }

        // B两个角都在
        if (b1IsInRectangle && b2IsInRectangle) {
            width = Math.abs(bx2 - bx1);
            height = Math.abs(by1 - ay2);

            return Math.abs(width) * Math.abs(height);
        }

        if (b2IsInRectangle && b3IsInRectangle) {
            width = Math.abs(bx2 - ax1);
            height = Math.abs(by1 - by2);

            return Math.abs(width) * Math.abs(height);
        }

        if (b3IsInRectangle && b4IsInRectangle) {
            width = Math.abs(bx2 - bx1);
            height = Math.abs(by2 - ay1);

            return Math.abs(width) * Math.abs(height);
        }

        if (b4IsInRectangle && b1IsInRectangle) {
            width = Math.abs(bx1 - ax2);
            height = Math.abs(by2 - by1);

            return Math.abs(width) * Math.abs(height);
        }

        return 0;
    }

    private static boolean isInRectangle(int x, int y,
                                         int x1, int y1, int x2, int y2) {
        if (x >= x1 && x <= x2 && y >= y1 && y <= y2) {
            return true;
        }
        return false;
    }

    /**
     *
     * 计算两个矩形宽，在x轴投影重叠部分
     * 计算两个矩形高，在y轴投影重叠部分
     *
     * 如何计算投影重叠：
     *
     * 前面的x 最小  - 后面的x 最大
     * Math.min(ax2, bx2) - Math.max(ax1, bx1);
     *
     * 前面的y 最小  - 后面的y 最大
     * Math.min(ay2, by2) - Math.max(ay1, by1);
     *
     * 重叠面积：重叠宽度 * 重叠高度
     *
     * @param ax1
     * @param ay1
     * @param ax2
     * @param ay2
     * @param bx1
     * @param by1
     * @param bx2
     * @param by2
     * @return
     */
    private static int computeArea3(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) {
        int width = Math.min(ax2, bx2) - Math.max(ax1, bx1);
        int height = Math.min(ay2, by2) - Math.max(ay1, by1);

        if (width > 0 && height > 0) {
            return Math.abs(width) * Math.abs(height);
        }
        return 0;
    }
}